package com.hps.lock;

import org.redisson.Redisson;
import org.redisson.api.RAtomicLong;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * @author heps
 * @date 2019/1/21 16:25
 */
public class RedissonUtil {

    private static final String RAtomicName = "genId_";

    private static Config config = new Config();
    private static RedissonClient redisson = null;
    private static boolean b = false;

    private RLock lock;

    public static void init(){
        try {
            config.useSingleServer() //这是用的集群server
            .setAddress("redis://127.0.0.1:6379");
            redisson = Redisson.create(config);
            //清空自增的ID数字
            RAtomicLong atomicLong = redisson.getAtomicLong(RAtomicName);
            atomicLong.set(1);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public static RedissonClient getRedisson(){
        if (!b) {
            init();
            b = true;
        }
        return redisson;
    }

    /** 获取redis中的原子ID */
    public static Long nextID(){
        RAtomicLong atomicLong = getRedisson().getAtomicLong(RAtomicName);
        atomicLong.incrementAndGet();
        return atomicLong.get();
    }

    public boolean lock(String key) {
        lock = getRedisson().getLock(key);
        try {
            boolean result = lock.tryLock(100, 1000, TimeUnit.MILLISECONDS);
            if (result) {
                return true;
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return false;
    }

    public void release() {
        lock.unlock();
    }

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        List<Integer> list = new ArrayList<>();
        list.add(0);
        int taskNum = 1000;
        CountDownLatch latch = new CountDownLatch(taskNum);
        for (int i = 0; i < taskNum; i++) {
            executorService.submit(() -> {
                RedissonUtil redissonUtil = new RedissonUtil();
                boolean result = redissonUtil.lock("rLock");
                if (result) {
                    Integer num = list.get(list.size() - 1);
                    list.add(++num);
                    redissonUtil.release();
                }
                latch.countDown();
            });
        }

        try {
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        executorService.shutdownNow();
        System.out.println(list.size());
        System.out.println(list);
    }
}
